package cn.ulc.socket.common.api;

import cn.hutool.core.util.NumberUtil;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import cn.ulc.common.constant.PubDataConstant;
import cn.ulc.common.util.CommonUtil;
import cn.ulc.socket.common.helper.MiniAppPayHelper;
import cn.ulc.store.dao.DepositDao;
import cn.ulc.store.dao.DepositOrderDao;
import cn.ulc.store.dao.DepositOrderItemDao;
import cn.ulc.store.dao.goods.GoodsSpecDao;
import cn.ulc.store.dao.order.OrderDao;
import cn.ulc.store.dao.order.OrderItemDao;
import cn.ulc.store.dao.user.WeixinUserDao;
import cn.ulc.store.entity.Deposit;
import cn.ulc.store.entity.DepositOrder;
import cn.ulc.store.entity.goods.GoodsSpec;
import cn.ulc.store.entity.order.Order;
import cn.ulc.store.entity.order.OrderItem;
import cn.ulc.store.entity.user.WeixinUser;
import com.github.binarywang.wxpay.bean.result.WxPayRefundResult;
import com.github.binarywang.wxpay.service.WxPayService;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Component;

import java.util.*;

@Component
@AllArgsConstructor
public class WxPayAPI {
  private static final Log log = LogFactory.get();

  OrderDao orderDao;
  OrderItemDao orderItemDao;
  GoodsSpecDao specDao;
  DepositDao depositDao;
  DepositOrderDao depositOrderDao;
  DepositOrderItemDao depositOrderItemDao;
  WeixinUserDao wxUserDao;

  WxPayService wxPayService;
  /**
   * 微信退款  整单退款
   *
   * @param orderNo
   */
  public Map<String , Object> wxRefund(String orderNo) {
    Map<String , Object> resultMap = new HashMap<>();
    Order order = orderDao.findByOrderNo(orderNo);
    WeixinUser member = wxUserDao.findOne(order.getWxUserId());
    if(order == null || member == null) {
      resultMap.put("success" , false);
      resultMap.put("msg" , "订单不存在或已删除");
      log.info("订单不存在或已删除");
      return resultMap;
    }
    if(PubDataConstant.ORDER_REFUND.equals(order.getStatus())) {
      resultMap.put("success" , false);
      resultMap.put("msg" , "订单已退款 不能重复退款");
      log.info("订单已退款 不能重复退款");
      return resultMap;
    }
    try {
      String refundNo = CommonUtil.generateRandomNumberString(6);;
      WxPayRefundResult refundResult = wxPayService.refund(MiniAppPayHelper.refundInfo(order.getOrderNo(),refundNo,order.getTransactionId(),order.getPayAmount(),order.getPayAmount()));
      if(refundResult != null) {
        log.info("退款订单号："+refundResult.getOutTradeNo() +" | 微信退款单号： " + refundResult.getRefundId());

        log.info("=================退款 保存订单 退款信息");
        order.setVerifyAt(new Date()); //当前时间
        order.setRefundId(refundResult.getRefundId());
        order.setRefundedAmount(order.getPayAmount());
        order.setStatus(PubDataConstant.ORDER_REFUND);
        orderDao.save(order);

        // 处理订单商品
        List<OrderItem> itemList = orderItemDao.findListByOrderId(order.getId());
        if(itemList != null && itemList.size()>0){
          // 若有水 则处理押金信息
          boolean hasWater = false;
          List<GoodsSpec> specList = new ArrayList<>();
          for (OrderItem item : itemList) {
            if(PubDataConstant.TYPE_DEPOSIT.equals(item.getMode())){
              hasWater = true;
            }else{
              // 商品库存
              GoodsSpec spec = item.getGoodsSpec();
              spec.setModifyAt(new Date());
              spec.setStock(spec.getStock().add(item.getNum()));
            }
          }
          if(specList.size()>0){
            specDao.saveAll(specList);
          }
          if(hasWater) {
            List<Deposit> depositList = depositDao.findByOrderNo(order.getOrderNo());
            if (depositList != null && depositList.size() > 0) {
              depositList.stream().forEach(d -> {
                d.setModifyAt(new Date());
                d.setStatus(PubDataConstant.ORDER_REFUND);
              });
              depositDao.saveAll(depositList);
            }
          }
        }
        resultMap.put("success" , true);
        resultMap.put("msg" , "退款成功");
      } else {
        resultMap.put("success" , false);
        resultMap.put("msg" , "WxPayRefundResult 为空");
      }
    } catch (Exception e) {
      log.info("Exception : " + e.getMessage());
      resultMap.put("success" , false);
      resultMap.put("msg" , e.getMessage());
    }
    return resultMap;
  }

  public Map<String , Object> depositRefund(String refundNo){
    Map<String , Object> resultMap = new HashMap<>();
    DepositOrder order = depositOrderDao.findByOrderNo(refundNo);
    Order tradeOrder = orderDao.findByOrderNo(order.getTradeNo());
    WeixinUser member = wxUserDao.findOne(order.getWxUserId());
    if(tradeOrder == null || order == null || member == null) {
      resultMap.put("success" , false);
      resultMap.put("msg" , "订单不存在或已删除");
      log.info("订单不存在或已删除");
      return resultMap;
    }
    if(PubDataConstant.ORDER_REFUND.equals(tradeOrder.getStatus())) {
      resultMap.put("success" , false);
      resultMap.put("msg" , "订单已退款 不能重复退款");
      log.info("订单已退款 不能重复退款");
      return resultMap;
    }
    // 检查订单商品是否存在已被退款
    if( !depositOrderItemDao.checkRefundItem(order.getId()) ){
      resultMap.put("success" , false);
      resultMap.put("msg" , "订单商品数目不匹配");
      log.info("订单商品数目不匹配 不能重复退款");
      return resultMap;
    }
    try {
      WxPayRefundResult refundResult = wxPayService.refund(MiniAppPayHelper.refundInfo(order.getTradeNo(),order.getOrderNo(),order.getTransactionId(),tradeOrder.getPayAmount(),order.getPayAmount()));
      if(refundResult != null) {
        log.info("退款订单号："+refundResult.getOutTradeNo() +" | 微信退款单号： " + refundResult.getRefundId());

        log.info("=================退款 保存订单 退款信息");
        order.setVerifyAt(new Date()); //当前时间
        order.setRefundId(refundResult.getRefundId());
        order.setStatus(PubDataConstant.ORDER_PAID);
        tradeOrder.setRefundedAmount(NumberUtil.add(tradeOrder.getRefundedAmount(),order.getPayAmount()));
        // 如果退款金额 大于等于 订单金额 ，则订单状态为退款状态
        // 退款金额大于订单金额一般不会出现 ，这里写大于是保障
        if(tradeOrder.getRefundedAmount().compareTo(tradeOrder.getPayAmount())>=0)
          tradeOrder.setStatus(PubDataConstant.ORDER_REFUND);
        // 如果 订单退款之后订单状态 未改为退款状态，则说明订单是部分退款 ， 则需重新生成 退款单号
//        if(orders.status != OrderStatus.REFUND)
//          orders.refundNo = RandomNumberUtil.generateRandomNumberString(6);
        orderDao.save(tradeOrder);

        depositOrderDao.save(order);

        resultMap.put("success" , true);
        resultMap.put("msg" , "退款成功");
      } else {
        resultMap.put("success" , false);
        resultMap.put("msg" , "WxPayRefundResult 为空");
      }
    } catch (Exception e) {
      log.info("Exception : " + e.getMessage());
      resultMap.put("success" , false);
      resultMap.put("msg" , e.getMessage());
    }
    return resultMap;
  }
}
